package cn.doitedu.kafka.day02

import java.time.Duration
import java.util
import java.util.Properties

import org.apache.kafka.clients.consumer.KafkaConsumer
import org.apache.kafka.common.serialization.StringDeserializer

/**
 * 消费者在消费数据的时候，会记录偏移量吗？偏移量记录在哪里呢？
 *   默认情况下，消费者会定期（5秒）将偏移量写入到Kafka特殊的topic中（__consumer_offsets）
 *   /kafka-console-consumer.sh --bootstrap-server  node-1.51doit.cn:9092,node-2.51doit.cn:9092,node-3.51doit.cn:9092 --topic __consumer_offsets --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter"
 *
 * 如果程序重启，会接着以前的偏移量继续读吗？
 *   如果不修改消费者组ID，会接着以前的偏移量继续读取
 *
 * 决定偏移量的因素有3个
 *  消费者组ID
 *  topic
 *  分区
 *
 * 每个topic，每个分区，每个消费者组ID，都对应一个唯一的偏移量
 *
 */
object ConsumerDemo2 {

  def main(args: Array[String]): Unit = {

    val properties = new Properties()
    //指定broker地址
    properties.setProperty("bootstrap.servers", "node-1.51doit.cn:9092,node-2.51doit.cn:9092,node-3.51doit.cn:9092")
    //指定key反序列化方式
    properties.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    //指定value反序列化方式
    properties.setProperty("value.deserializer", classOf[StringDeserializer].getName) // 两种写法都行
    //指定消费者组ID
    properties.setProperty("group.id", "g1110")
    //从头开始消费
    //earliest：从头开始 --from-beginning
    //latest:从消费者启动之后
    //如果指定了"auto.offset.reset","earliest"，消费者启动是会读取对应消费者组ID的偏移量
    //如果没有历史偏移量，就从头读，有偏移量，就继续读
    properties.setProperty("auto.offset.reset","earliest") //[latest, earliest, none]
    //是不是开启自动提交偏移量，默认为true
    //到底是自动更新偏移量好，（更方便）
    //还是手动更新偏移量好呢？ (更精准)
    properties.setProperty("enable.auto.commit","false")
    //提交偏移量的周期时间，默认是5秒,开启自动提交时，才有效
    //properties.setProperty("auto.commit.interval.ms", "2000")

    //创建KafkaConsumer，并关联properties
    val consumer = new KafkaConsumer[String, String](properties)

    val topics: util.List[String] = util.Arrays.asList("test")
    //订阅指定的一个或多个topic
    consumer.subscribe(topics)

    //不停地循环
    while (true) {
      //拉取数据，返回的是consumerRecords，是Iterable
      //如果拉取到一个批次数据，立即返回，如果没有拉取到新的数据，最多等待值的时间
      //println(666)
      val consumerRecords = consumer.poll(Duration.ofSeconds(10))
      //使用scala的for循环遍历
      import scala.collection.JavaConverters._
      for (record <- consumerRecords.asScala) {
        println(record)
      }
    }



  }
}
